home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-03-25 | 10.0 KB | 311 lines | [TEXT/MPS ] |
- {7.0fo.p}
-
- { A demo of 7.0 process manager calls and outline fonts. }
- { © 1991 Harry Chesley. }
-
- unit fo;
-
- interface
-
- uses
- Quickdraw, Sound, Files, Processes, Packages, Fonts,
- Memory, Toolutils, OSUtils, GestaltEqu, GraphicsModuleTypes;
-
- function DoInitialize (var storage: Handle; blankRgn: rgnHandle; params: GMParamBlockPtr): OSErr;
-
- function DoBlank (storage: Handle; blankRgn: rgnHandle; params: GMParamBlockPtr): OSErr;
-
- function DoDrawFrame (storage: Handle; blankRgn: rgnHandle; params: GMParamBlockPtr): OSErr;
-
- function DoClose (storage: Handle; blankRgn: RgnHandle; params: GMParamBlockPtr): OSErr;
-
- function DoSetup (blankRgn: rgnHandle; message: integer; params: GMParamBlockPtr): OSErr;
-
- implementation
-
- const
-
- kLimitOn100kSz = 600000; { Limit on size of processes displayed with outline. }
-
- kNoProcessManagerString = 1000; { No process manager error 'STR '. }
- kFontString = 1001; { Display font name 'STR '. }
-
- type
-
- { Our persistent data. }
- ourData =
- record
- fontNumber: integer; { Display font to use. }
- lastUpdate: longInt; { Time of last update. }
- end;
-
- ourPtr = ^ourData;
- ourHandle = ^ourPtr;
-
- function max3(a,b,c: integer): integer;
- { The max function for three integers. }
-
- begin
- if a > b then
- begin
- if a > c then max3 := a
- else max3 := c;
- end
- else
- begin
- if b > c then max3 := b
- else max3 := c;
- end;
- end;
-
- function DoInitialize (var storage: Handle; blankRgn: rgnHandle; params: GMParamBlockPtr): OSErr;
- { Intialize our globals. }
-
- var od: ourHandle;
- s: Str255;
- i: integer;
- osAttr: longInt;
- sHand: StringHandle;
-
- begin
- { Determine that the Process Manager is available. (Note: just calling Gestalt without first checking
- that it's available only works with MPW 3.2 and later.) }
- if Gestalt(gestaltOSAttr,osAttr) = noErr then
- if BitTst(@osAttr,31-gestaltLaunchControl) then
- begin
- { Allocate our storage. }
- storage := NewHandle(sizeof(ourData));
- if MemError <> noErr then
- begin
- DoInitialize := MemError;
- exit(DoInitialize);
- end;
- od := ourHandle(storage);
-
- { Get the font to use for displays. }
- s := GetString(kFontString)^^;
- GetFNum(s,i);
- od^^.fontNumber := i;
-
- { Force immediate update. }
- od^^.lastUpdate := 0;
-
- { Get really random numbers. }
- params^.qdGlobalsCopy^.qdRandSeed := TickCount;
-
- DoInitialize := noErr;
- exit(DoInitialize);
- end;
-
- sHand := GetString(kNoProcessManagerString);
- if sHand <> nil then params^.errorMessage^ := sHand^^
- else params^.errorMessage^ := 'This module requires the Process Manager (System 7.0 and later) to run.';
- DoInitialize := ModuleError;
- end;
-
- function DoBlank (storage: Handle; blankRgn: rgnHandle; params: GMParamBlockPtr): OSErr;
- { Blank the screen the first time. }
-
- begin
- { Dim according to the user's wishes. }
- params^.brightness := (params^.controlValues[0] * 255) div 100;
- { Black it out. }
- FillRgn(blankRgn, params^.qdGlobalsCopy^.qdBlack);
- DoBlank := noErr;
- end;
-
-
- function DoDrawFrame (storage: Handle; blankRgn: rgnHandle; params: GMParamBlockPtr): OSErr;
- { Go for it. }
-
- var od: ourHandle; { Handle to our data (coerced from storage). }
- monitor: integer; { Monitor we're displaying on. }
- r: Rect; { Rectangle of the current monitor. }
- descRect: Rect; { Rectangle for current process description. }
- i: integer;
- b: boolean;
- maxProcSz: longInt; { Size of largest process. }
- max100kProcSz: longInt; { Size of largest process under kLimitOn100kSz. }
- fontSize: integer; { Process name font size. }
- subFontSize: integer; { Process info font size. }
- fontFace: Style; { Font style. }
- psn: ProcessSerialNumber; { Process being processed. }
- frontPSN: ProcessSerialNumber; { Foreground process. }
- pInfo: ProcessInfoRec; { Info on current process. }
- fSpec: FSSpec; { File spec on current process. }
- launchTime: longInt; { Launch time of current process. }
- szStr: Str255; { Process size description. }
- cpuHrStr, cpuMinStr, cpuSecStr, cpuStr: Str255; { CPU time strings. }
- launchTimeStr, launchDateStr: Str255; { Launch date/time strings. }
- s1, s2, s3: Str255; { Line 1, 2, and 3 of the description. }
- w, h, v: integer; { Width and location of the description. }
- mainFontInfo: FontInfo; { Font info for process name line. }
- subFontInfo: FontInfo; { Font info for process description lines. }
- ignore: OSErr;
-
- begin
- { Dim as requested. }
- params^.brightness := (params^.controlValues[0] * 255) div 100;
-
- { Get our data. }
- od := OurHandle(storage);
- if od = nil then exit(DoDrawFrame);
-
- { Check if it's time to update display yet. }
- if TickCount < (od^^.lastUpdate + params^.controlValues[1] * 60) then exit(DoDrawFrame);
- od^^.lastUpdate := TickCount;
-
- { Set up process info structure. }
- pInfo.processInfoLength := sizeof(pInfo);
- pInfo.processName := @s1;
- pInfo.processAppSpec := @fSpec;
-
- { Get the largest sized processes. }
- maxProcSz := 0;
- max100kProcSz := 0;
- psn.highLongOfPSN := 0;
- psn.lowLongOfPSN := kNoProcess;
- while GetNextProcess(psn) = noErr do
- if GetProcessInformation(psn,pInfo) = noErr then
- begin
- if pInfo.processSize > maxProcSz then maxProcSz := pInfo.processSize;
- if (pInfo.processSize < kLimitOn100kSz) and (pInfo.processSize > max100kProcSz) then
- max100kProcSz := pInfo.processSize;
- end;
-
- { Get foreground process. }
- ignore := GetFrontProcess(frontPSN);
-
- { Set up pen for drawing. }
- PenNormal;
- backColor(whiteColor);
- foreColor(blackColor);
- { Blank screen. }
- FillRgn(blankRgn, params^.qdGlobalsCopy^.qdBlack);
- { Draw white/black or black/white. }
- if params^.controlValues[2] = 0 then
- begin
- backColor(blackColor);
- foreColor(whiteColor);
- end;
- { Select the font. }
- TextFont(od^^.fontNumber);
-
- { For each monitor... }
- for monitor := 0 to params^.monitors^.monitorCount-1 do
- begin
- r := params^.monitors^.monitorList[monitor].bounds;
-
- { For each process... }
- psn.highLongOfPSN := 0;
- psn.lowLongOfPSN := kNoProcess;
- while GetNextProcess(psn) = noErr do
- begin
- { Try to get the process's info. }
- if GetProcessInformation(psn,pInfo) <> noErr then
- begin
- { If things failed, display at error code. }
- fontSize := 24;
- subFontSize := 12;
- fontFace := [];
- s1 := 'GetProcessInformation Error';
- NumToString(GetProcessInformation(psn,pInfo),s2);
- s3 := '';
- end
- else
- begin
- { Compute the font size and style. }
- if pInfo.processSize < kLimitOn100kSz then
- begin
- fontFace := [];
- fontSize := (((r.bottom - r.top) div 10) * pInfo.processSize) div max100kProcSz;
- end
- else
- begin
- fontFace := [bold];
- fontSize := (((r.bottom - r.top) div 10) * pInfo.processSize) div maxProcSz;
- end;
- if fontSize < 12 then fontSize := 12;
- subFontSize := fontSize div 2;
- if subFontSize < 10 then subFontSize := 10;
- if SameProcess(psn,frontPSN,b) = noErr then
- if b then fontFace := fontFace + [italic];
-
- { Create the description to display. }
- NumToString(pInfo.processSize div 1024,szStr);
- pInfo.processActiveTime := pInfo.processActiveTime div 60;
- NumToString(pInfo.processActiveTime div 3600,cpuHrStr);
- if length(cpuHrStr) = 1 then cpuHrStr := Concat('0',cpuHrStr);
- NumToString((pInfo.processActiveTime div 60) mod 60,cpuMinStr);
- if length(cpuMinStr) = 1 then cpuMinStr := Concat('0',cpuMinStr);
- NumToString(pInfo.processActiveTime mod 60,cpuSecStr);
- if length(cpuSecStr) = 1 then cpuSecStr := Concat('0',cpuSecStr);
- GetDateTime(launchTime);
- launchTime := launchTime - (TickCount - pInfo.processLaunchDate) div 60;
- IUTimeString(launchTime,false,launchTimeStr);
- IUDateString(launchTime,abbrevDate,launchDateStr);
- s2 := Concat('Launched: ',launchTimeStr,' on ',launchDateStr);
- s3 := Concat('Size: ',szStr,'k; CPU time: ',cpuHrStr,':',cpuMinStr,':',cpuSecStr);
- end;
-
- { Pick a random location for the text that's certain to show. }
- if fontSize = 12 then fontFace := fontFace - [outline];
- TextFace(fontFace);
- TextSize(fontSize);
- { Note: srcCopy in text mode is not recommended (according to Inside Mac I), but it works for us here. }
- TextMode(srcCopy);
- GetFontInfo(mainFontInfo);
- w := StringWidth(s1);
- TextSize(subFontSize);
- GetFontInfo(subFontInfo);
- w := max3(w,StringWidth(s2),StringWidth(s3));
- h := r.right - r.left - w - 20;
- if h <= 0 then h := 1;
- h := r.left + 10 + abs(Random mod h);
- v := r.top + 10 + mainFontInfo.ascent;
- v := v + abs(Random mod (r.bottom - r.top - 20 - mainFontInfo.ascent - mainFontInfo.descent -
- 2 * (subFontInfo.leading + subFontInfo.ascent + subFontInfo.descent)));
- descRect.top := v-mainFontInfo.ascent-10;
- descRect.left := h-10;
- descRect.bottom := v+mainFontInfo.descent +
- 2 * (subFontInfo.leading+subFontInfo.ascent+subFontInfo.descent) + 10;
- descRect.right := h + w + 10;
-
- { Draw the box. }
- FillRoundRect(descRect, 20, 20, params^.qdGlobalsCopy^.qdWhite);
- FrameRoundRect(descRect, 20, 20);
-
- { Draw the process name. }
- TextSize(fontSize);
- MoveTo(h,v);
- DrawString(s1);
-
- { Draw the process info. }
- TextSize(subFontSize);
- MoveTo(h,v+mainFontInfo.descent+subFontInfo.leading+subFontInfo.ascent);
- DrawString(s2);
- MoveTo(h,v+mainFontInfo.descent+subFontInfo.descent+ 2 * (subFontInfo.leading+subFontInfo.ascent));
- DrawString(s3);
- end;
- end;
-
- DoDrawFrame := noErr;
-
- end;
-
- function DoClose (storage: Handle; blankRgn: RgnHandle; params: GMParamBlockPtr): OSErr;
- { Free our persistent data. }
-
- begin
- if storage <> nil then DisposHandle(storage);
- DoClose := noErr;
- end;
-
- function DoSetup (blankRgn: rgnHandle; message: integer; params: GMParamBlockPtr): OSErr;
- {This is called when the used clicks on a button in the Control Panel.}
-
- begin
- DoSetup := noErr;
- end;
-
- end.